package com.geek.factory.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.geek.factory.constant.SuccessConstant;
import com.geek.factory.entity.InventoryDistribution;
import com.geek.factory.entity.Material;
import com.geek.factory.entity.Product;
import com.geek.factory.entity.StockCheckDetail;
import com.geek.factory.entity.StockCheckAdjustment;
import com.geek.factory.entity.Warehouse;
import com.geek.factory.entity.Shelves;
import com.geek.factory.result.Result;
import com.geek.factory.service.IInventoryDistributionService;
import com.geek.factory.service.IMaterialService;
import com.geek.factory.service.IProductService;
import com.geek.factory.service.IStockCheckDetailService;
import com.geek.factory.service.IStockCheckAdjustmentService;
import com.geek.factory.service.IWarehouseService;
import com.geek.factory.service.IShelvesService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 库存盘点明细管理控制器
 */
@RestController
@RequestMapping("/stock-check-detail")
@Api(tags = "后台系统的 - 库存盘点明细模块")
@Slf4j
@CrossOrigin
public class StockCheckDetailController {

    @Autowired
    private IStockCheckDetailService stockCheckDetailService;

    @Autowired
    private IInventoryDistributionService inventoryDistributionService;

    @Autowired
    private IProductService productService;

    @Autowired
    private IMaterialService materialService;

    @Autowired
    private IWarehouseService warehouseService;

    @Autowired
    private IStockCheckAdjustmentService stockCheckAdjustmentService;

    @Autowired
    private IShelvesService shelvesService;

    @ApiOperation("通过ID查询库存盘点明细信息")
    @GetMapping("/{detailId}")
    public Result findStockCheckDetailById(@ApiParam("明细ID") @PathVariable("detailId") Integer detailId) {
        StockCheckDetail stockCheckDetail = stockCheckDetailService.getById(detailId);
        log.info("stockCheckDetail: {}", stockCheckDetail);
        if (stockCheckDetail != null) {
            // 添加关联信息
            Map<String, Object> enrichedDetail = enrichDetailWithInfo(stockCheckDetail);
            return new Result(SuccessConstant.SUCCESS, "ok", enrichedDetail);
        }
        return new Result(SuccessConstant.FAIL, "库存盘点明细记录不存在");
    }

    @ApiOperation("新增库存盘点明细")
    @PostMapping
    public Result addStockCheckDetail(@RequestBody StockCheckDetail stockCheckDetail) {
        // 设置默认值
        stockCheckDetail.setCreatedTime(LocalDateTime.now());
        stockCheckDetail.setUpdatedTime(LocalDateTime.now());

        // 计算差异数量
        if (stockCheckDetail.getSystemQuantity() != null && stockCheckDetail.getActualQuantity() != null) {
            BigDecimal difference = stockCheckDetail.getActualQuantity().subtract(stockCheckDetail.getSystemQuantity());
            stockCheckDetail.setDifference(difference);
        }

        boolean isSuccess = stockCheckDetailService.save(stockCheckDetail);
        log.info("新增库存盘点明细: {}, 结果: {}", stockCheckDetail, isSuccess);
        if (isSuccess) {
            // 添加关联信息
            Map<String, Object> enrichedDetail = enrichDetailWithInfo(stockCheckDetail);
            return new Result(SuccessConstant.SUCCESS, "新增成功", enrichedDetail);
        }
        return new Result(SuccessConstant.FAIL, "新增失败");
    }

    @ApiOperation("根据ID删除库存盘点明细")
    @DeleteMapping("/{detailId}")
    public Result deleteStockCheckDetail(@ApiParam("明细ID") @PathVariable("detailId") Integer detailId) {
        boolean isSuccess = stockCheckDetailService.removeById(detailId);
        log.info("删除库存盘点明细ID: {}, 结果: {}", detailId, isSuccess);
        if (isSuccess) {
            return new Result(SuccessConstant.SUCCESS, "删除成功");
        }
        return new Result(SuccessConstant.FAIL, "删除失败");
    }

    @ApiOperation("批量删除库存盘点明细")
    @DeleteMapping("/batch")
    public Result batchDeleteStockCheckDetail(@RequestBody Map<String, List<Integer>> request) {
        List<Integer> detailIds = request.get("detailIds");
        if (detailIds == null || detailIds.isEmpty()) {
            return new Result(SuccessConstant.FAIL, "请选择要删除的盘点明细记录");
        }

        boolean isSuccess = stockCheckDetailService.removeByIds(detailIds);
        log.info("批量删除库存盘点明细IDs: {}, 结果: {}", detailIds, isSuccess);
        if (isSuccess) {
            return new Result(SuccessConstant.SUCCESS, "批量删除成功");
        }
        return new Result(SuccessConstant.FAIL, "批量删除失败");
    }

    @ApiOperation("修改库存盘点明细信息")
    @PutMapping("/{detailId}")
    public Result updateStockCheckDetail(@ApiParam("明细ID") @PathVariable("detailId") Integer detailId, @RequestBody StockCheckDetail stockCheckDetail) {
        stockCheckDetail.setDetailId(detailId);
        stockCheckDetail.setUpdatedTime(LocalDateTime.now());

        // 重新计算差异数量
        if (stockCheckDetail.getSystemQuantity() != null && stockCheckDetail.getActualQuantity() != null) {
            BigDecimal difference = stockCheckDetail.getActualQuantity().subtract(stockCheckDetail.getSystemQuantity());
            stockCheckDetail.setDifference(difference);
        }

        boolean isSuccess = stockCheckDetailService.updateById(stockCheckDetail);
        log.info("修改库存盘点明细: {}, 结果: {}", stockCheckDetail, isSuccess);
        if (isSuccess) {
            // 添加关联信息
            Map<String, Object> enrichedDetail = enrichDetailWithInfo(stockCheckDetail);
            return new Result(SuccessConstant.SUCCESS, "修改成功", enrichedDetail);
        }
        return new Result(SuccessConstant.FAIL, "修改失败");
    }

    @ApiOperation("根据盘点单ID查询明细列表")
    @GetMapping("/check/{checkId}")
    public Result getDetailsByCheckId(@ApiParam("盘点单ID") @PathVariable("checkId") Integer checkId) {
        QueryWrapper<StockCheckDetail> wrapper = new QueryWrapper<>();
        wrapper.eq("check_id", checkId);
        wrapper.orderByDesc("created_time");

        List<StockCheckDetail> details = stockCheckDetailService.list(wrapper);
        // 添加关联信息
        List<Map<String, Object>> enrichedDetails = details.stream()
                .map(this::enrichDetailWithInfo)
                .collect(Collectors.toList());
        return new Result(SuccessConstant.SUCCESS, "查询成功", enrichedDetails);
    }

    @ApiOperation("分页查询库存盘点明细列表")
    @GetMapping("/page")
    public Result getStockCheckDetailPage(
            @RequestParam(defaultValue = "1") Integer pageNum,
            @RequestParam(defaultValue = "10") Integer pageSize,
            @RequestParam(required = false) Integer checkId,
            @RequestParam(required = false) String itemType,
            @RequestParam(required = false) Integer productId,
            @RequestParam(required = false) Integer materialId,
            @RequestParam(required = false) Integer shelfId
    ) {
        QueryWrapper<StockCheckDetail> wrapper = new QueryWrapper<>();
        if (checkId != null) {
            wrapper.eq("check_id", checkId);
        }
        if (StringUtils.isNotBlank(itemType)) {
            wrapper.eq("item_type", itemType);
        }
        if (productId != null) {
            wrapper.eq("product_id", productId);
        }
        if (materialId != null) {
            wrapper.eq("material_id", materialId);
        }
        if (shelfId != null) {
            wrapper.eq("shelf_id", shelfId);
        }
        wrapper.orderByDesc("created_time");

        Page<StockCheckDetail> page = stockCheckDetailService.page(new Page<>(pageNum, pageSize), wrapper);

        // 添加关联信息
        List<Map<String, Object>> enrichedRecords = page.getRecords().stream()
                .map(this::enrichDetailWithInfo)
                .collect(Collectors.toList());

        Map<String, Object> data = new HashMap<>();
        data.put("records", enrichedRecords);
        data.put("total", page.getTotal());
        data.put("current", page.getCurrent());
        data.put("size", page.getSize());
        data.put("pages", page.getPages());

        return new Result(SuccessConstant.SUCCESS, "查询成功", data);
    }

    @ApiOperation("获取所有库存盘点明细列表")
    @GetMapping("/list")
    public Result getAllStockCheckDetails(
            @RequestParam(required = true) Integer checkId,
            @RequestParam(required = false) String itemType,
            @RequestParam(required = false) Boolean hasDifference
    ) {
        log.info("获取盘点明细列表参数: checkId={}, itemType={}, hasDifference={}", checkId, itemType, hasDifference);

        try {
            // 构建查询条件
            QueryWrapper<StockCheckDetail> wrapper = new QueryWrapper<>();
            wrapper.eq("check_id", checkId);

            if (StringUtils.isNotBlank(itemType)) {
                wrapper.eq("item_type", itemType);
            }

            if (hasDifference != null) {
                if (hasDifference) {
                    // 有差异（不为0）
                    wrapper.ne("difference", 0);
                } else {
                    // 无差异（等于0或为null）
                    wrapper.eq("difference", 0).or().isNull("difference");
                }
            }

            wrapper.orderByDesc("created_time");

            log.info("查询SQL条件: {}", wrapper.getSqlSegment());
            List<StockCheckDetail> details = stockCheckDetailService.list(wrapper);

            log.info("查询到盘点明细数量: {}", details.size());

            // 添加关联信息
            List<Map<String, Object>> enrichedDetails = new ArrayList<>();
            for (StockCheckDetail detail : details) {
                Map<String, Object> enrichedDetail = enrichDetailWithInfo(detail);
                enrichedDetails.add(enrichedDetail);
            }

            // 构建返回格式与分页接口一致
            Map<String, Object> data = new HashMap<>();
            data.put("records", enrichedDetails);
            data.put("total", enrichedDetails.size());

            return new Result(SuccessConstant.SUCCESS, "查询成功", data);
        } catch (Exception e) {
            log.error("查询盘点明细异常", e);
            return new Result(SuccessConstant.FAIL, "查询失败: " + e.getMessage());
        }
    }

    @ApiOperation("获取盘点明细统计信息")
    @GetMapping("/stats/{checkId}")
    public Result getStockCheckDetailStats(@ApiParam("盘点单ID") @PathVariable("checkId") Integer checkId) {
        Map<String, Object> stats = new HashMap<>();

        QueryWrapper<StockCheckDetail> wrapper = new QueryWrapper<>();
        wrapper.eq("check_id", checkId);

        // 统计总数
        long totalCount = stockCheckDetailService.count(wrapper);

        // 统计有差异的数量
        QueryWrapper<StockCheckDetail> diffWrapper = new QueryWrapper<>();
        diffWrapper.eq("check_id", checkId);
        diffWrapper.ne("difference", 0);
        long diffCount = stockCheckDetailService.count(diffWrapper);

        // 统计无差异的数量
        QueryWrapper<StockCheckDetail> noDiffWrapper = new QueryWrapper<>();
        noDiffWrapper.eq("check_id", checkId);
        noDiffWrapper.eq("difference", 0);
        long noDiffCount = stockCheckDetailService.count(noDiffWrapper);

        stats.put("totalCount", totalCount);
        stats.put("diffCount", diffCount);
        stats.put("noDiffCount", noDiffCount);
        stats.put("diffRate", totalCount > 0 ? (double) diffCount / totalCount * 100 : 0);

        return new Result(SuccessConstant.SUCCESS, "查询成功", stats);
    }

    @ApiOperation("从库存分布生成盘点明细")
    @PostMapping("/generate")
    public Result generateCheckDetails(@RequestBody Map<String, Object> params) {
        Integer checkId = (Integer) params.get("checkId");
        Integer warehouseId = (Integer) params.get("warehouseId");
        String itemType = (String) params.get("itemType");

        if (checkId == null || warehouseId == null) {
            return new Result(SuccessConstant.FAIL, "参数不完整, 需要checkId和warehouseId");
        }

        log.info("开始生成盘点明细，参数: checkId={}, warehouseId={}, itemType={}", checkId, warehouseId, itemType);

        try {
            // 查找所有可用的仓库ID
            List<InventoryDistribution> allInventory = inventoryDistributionService.list();
            List<Integer> availableWarehouseIds = allInventory.stream()
                    .map(InventoryDistribution::getWarehouseId)
                    .distinct()
                    .collect(Collectors.toList());

            log.info("数据库中可用的仓库ID: {}", availableWarehouseIds);

            // 检查指定的仓库ID是否在可用列表中
            if (!availableWarehouseIds.contains(warehouseId)) {
                return new Result(SuccessConstant.FAIL,
                        "仓库ID=" + warehouseId + "在库存分布表中不存在。可用的仓库ID: " + availableWarehouseIds);
            }

            // 先检查是否存在库存分布数据
            QueryWrapper<InventoryDistribution> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("warehouse_id", warehouseId);
            if ("product".equals(itemType)) {
                queryWrapper.isNotNull("product_id");
            } else if ("material".equals(itemType)) {
                queryWrapper.isNotNull("material_id");
            }
            // 如果itemType为"all"或null，则不添加额外条件，查询所有类型

            long count = inventoryDistributionService.count(queryWrapper);
            log.info("符合条件的库存分布记录数: {}", count);

            if (count == 0) {
                return new Result(SuccessConstant.FAIL, "仓库ID=" + warehouseId + "没有找到" +
                        (itemType != null ? itemType + "类型的" : "") + "库存分布记录");
            }

            boolean success = stockCheckDetailService.generateDetailsFromInventory(checkId, warehouseId, itemType);

            if (success) {
                // 验证是否成功生成明细
                QueryWrapper<StockCheckDetail> detailQuery = new QueryWrapper<>();
                detailQuery.eq("check_id", checkId);
                if ("product".equals(itemType)) {
                    detailQuery.eq("item_type", "product");
                } else if ("material".equals(itemType)) {
                    detailQuery.eq("item_type", "material");
                }
                // 如果itemType为"all"或null，则不添加额外条件，查询所有类型
                
                long detailCount = stockCheckDetailService.count(detailQuery);

                log.info("生成盘点明细成功，共生成 {} 条记录", detailCount);

                if (detailCount > 0) {
                    return new Result(SuccessConstant.SUCCESS, "生成明细成功，共生成 " + detailCount + " 条记录");
                } else {
                    return new Result(SuccessConstant.FAIL, "未能生成盘点明细记录");
                }
            } else {
                log.error("生成盘点明细失败");
                return new Result(SuccessConstant.FAIL, "生成明细失败，请检查后台日志");
            }
        } catch (Exception e) {
            log.error("生成盘点明细过程中发生异常", e);
            return new Result(SuccessConstant.FAIL, "生成明细异常: " + e.getMessage());
        }
    }

    @ApiOperation("更新盘点明细的实际数量")
    @PutMapping("/{detailId}/actual-quantity")
    @Transactional
    public Result updateActualQuantity(
            @ApiParam("明细ID") @PathVariable("detailId") Integer detailId,
            @RequestBody Map<String, Object> request
    ) {
        BigDecimal actualQuantity = new BigDecimal(request.get("actualQuantity").toString());
        String remarks = (String) request.get("remarks");

        StockCheckDetail detail = stockCheckDetailService.getById(detailId);
        if (detail == null) {
            return new Result(SuccessConstant.FAIL, "盘点明细不存在");
        }

        // 更新实际数量和差异数量
        detail.setActualQuantity(actualQuantity);
        detail.setDifference(actualQuantity.subtract(detail.getSystemQuantity()));
        detail.setRemarks(remarks);
        detail.setCheckStatus("checked"); // 设置为已盘点状态
        detail.setUpdatedTime(LocalDateTime.now());

        boolean isSuccess = stockCheckDetailService.updateById(detail);
        log.info("更新盘点明细实际数量: detailId={}, actualQuantity={}, difference={}, 结果={}",
                detailId, actualQuantity, detail.getDifference(), isSuccess);

        if (isSuccess) {
            Map<String, Object> result = enrichDetailWithInfo(detail);
            return new Result(SuccessConstant.SUCCESS, "更新成功", result);
        }
        return new Result(SuccessConstant.FAIL, "更新失败");
    }

    @ApiOperation("提交差异调整申请")
    @PostMapping("/{detailId}/adjustment")
    @Transactional
    public Result submitAdjustment(
            @ApiParam("明细ID") @PathVariable("detailId") Integer detailId,
            @RequestBody StockCheckAdjustment adjustment
    ) {
        StockCheckDetail detail = stockCheckDetailService.getById(detailId);
        if (detail == null) {
            return new Result(SuccessConstant.FAIL, "盘点明细不存在");
        }

        // 检查是否存在差异
        if (detail.getDifference() == null || detail.getDifference().compareTo(BigDecimal.ZERO) == 0) {
            return new Result(SuccessConstant.FAIL, "该明细没有差异，无需调整");
        }

        // 设置调整记录的基本信息
        adjustment.setDetailId(detailId);
        adjustment.setCheckId(detail.getCheckId());
        adjustment.setAdjustmentQuantity(detail.getDifference());
        adjustment.setCreatedTime(LocalDateTime.now());
        adjustment.setUpdatedTime(LocalDateTime.now());

        boolean isSuccess = stockCheckAdjustmentService.save(adjustment);
        log.info("提交差异调整申请: detailId={}, adjustmentType={}, reason={}, 结果={}",
                detailId, adjustment.getAdjustmentType(), adjustment.getReason(), isSuccess);

        if (isSuccess) {
            return new Result(SuccessConstant.SUCCESS, "提交成功", adjustment);
        }
        return new Result(SuccessConstant.FAIL, "提交失败");
    }

    @ApiOperation("审批差异调整")
    @PutMapping("/adjustment/{adjustmentId}/approve")
    @Transactional
    public Result approveAdjustment(
            @ApiParam("调整ID") @PathVariable("adjustmentId") Integer adjustmentId,
            @RequestBody Map<String, Object> request
    ) {
        String approvalResult = (String) request.get("approvalResult");
        String approvalComments = (String) request.get("approvalComments");
        String approvedBy = (String) request.get("approvedBy");

        StockCheckAdjustment adjustment = stockCheckAdjustmentService.getById(adjustmentId);
        if (adjustment == null) {
            return new Result(SuccessConstant.FAIL, "调整记录不存在");
        }

        // 更新审批信息
        adjustment.setApprovalResult(approvalResult);
        adjustment.setApprovalComments(approvalComments);
        adjustment.setApprovedBy(approvedBy);
        adjustment.setApprovedTime(LocalDateTime.now());
        adjustment.setUpdatedTime(LocalDateTime.now());

        boolean isSuccess = stockCheckAdjustmentService.updateById(adjustment);
        log.info("审批差异调整: adjustmentId={}, approvalResult={}, approvedBy={}, 结果={}",
                adjustmentId, approvalResult, approvedBy, isSuccess);

        if (isSuccess && "approved".equals(approvalResult)) {
            // 如果审批通过，更新库存分布
            StockCheckDetail detail = stockCheckDetailService.getById(adjustment.getDetailId());
            if (detail != null) {
                QueryWrapper<InventoryDistribution> wrapper = new QueryWrapper<>();
                if (detail.getProductId() != null) {
                    wrapper.eq("product_id", detail.getProductId());
                } else if (detail.getMaterialId() != null) {
                    wrapper.eq("material_id", detail.getMaterialId());
                }
                wrapper.eq("warehouse_id", detail.getShelfId());

                InventoryDistribution inventory = inventoryDistributionService.getOne(wrapper);
                if (inventory != null) {
                    // 更新库存数量为实际盘点数量
                    inventory.setQuantity(detail.getActualQuantity());
                    inventory.setUpdatedTime(LocalDateTime.now());
                    inventoryDistributionService.updateById(inventory);
                }
            }
        }

        if (isSuccess) {
            return new Result(SuccessConstant.SUCCESS, "审批成功", adjustment);
        }
        return new Result(SuccessConstant.FAIL, "审批失败");
    }

    @ApiOperation("获取明细的差异调整记录")
    @GetMapping("/{detailId}/adjustments")
    public Result getDetailAdjustments(@ApiParam("明细ID") @PathVariable("detailId") Integer detailId) {
        QueryWrapper<StockCheckAdjustment> wrapper = new QueryWrapper<>();
        wrapper.eq("detail_id", detailId);
        wrapper.orderByDesc("created_time");

        List<StockCheckAdjustment> adjustments = stockCheckAdjustmentService.list(wrapper);
        return new Result(SuccessConstant.SUCCESS, "查询成功", adjustments);
    }

    @ApiOperation("获取盘点单的所有差异调整记录")
    @GetMapping("/check/{checkId}/adjustments")
    public Result getCheckAdjustments(
            @ApiParam("盘点单ID") @PathVariable("checkId") Integer checkId,
            @RequestParam(required = false) String approvalResult
    ) {
        QueryWrapper<StockCheckAdjustment> wrapper = new QueryWrapper<>();
        wrapper.eq("check_id", checkId);
        if (StringUtils.isNotBlank(approvalResult)) {
            wrapper.eq("approval_result", approvalResult);
        }
        wrapper.orderByDesc("created_time");

        List<StockCheckAdjustment> adjustments = stockCheckAdjustmentService.list(wrapper);
        return new Result(SuccessConstant.SUCCESS, "查询成功", adjustments);
    }

    /**
     * 为盘点明细添加关联信息
     */
    private Map<String, Object> enrichDetailWithInfo(StockCheckDetail detail) {
        Map<String, Object> enriched = new HashMap<>();

        // 复制基本字段
        enriched.put("detailId", detail.getDetailId());
        enriched.put("checkId", detail.getCheckId());
        enriched.put("productId", detail.getProductId());
        enriched.put("materialId", detail.getMaterialId());
        enriched.put("itemType", detail.getItemType());
        enriched.put("systemQuantity", detail.getSystemQuantity());
        enriched.put("actualQuantity", detail.getActualQuantity());
        enriched.put("difference", detail.getDifference());
        enriched.put("unit", detail.getUnit());
        enriched.put("shelfId", detail.getShelfId());
        enriched.put("location", detail.getLocation());
        enriched.put("remarks", detail.getRemarks());
        enriched.put("createdTime", detail.getCreatedTime());
        enriched.put("updatedTime", detail.getUpdatedTime());
        enriched.put("checkStatus", detail.getCheckStatus());

        // 添加产品信息
        if (detail.getProductId() != null && "product".equals(detail.getItemType())) {
            Product product = productService.getById(detail.getProductId());
            if (product != null) {
                enriched.put("productName", product.getName());
                enriched.put("productCode", product.getModel()); // 使用model字段作为产品编码
            }
        }

        // 添加原料信息
        if (detail.getMaterialId() != null && "material".equals(detail.getItemType())) {
            Material material = materialService.getById(detail.getMaterialId());
            if (material != null) {
                enriched.put("materialName", material.getMaterialName());
                enriched.put("materialCode", material.getMaterialCode());
            }
        }

        // 添加货柜信息
        if (detail.getShelfId() != null) {
            Shelves shelf = shelvesService.getById(detail.getShelfId());
            if (shelf != null) {
                enriched.put("shelfName", shelf.getShelfName());
                enriched.put("shelfCode", shelf.getShelfCode());
                enriched.put("locationCode", shelf.getLocationCode());
            }
        }

        return enriched;
    }
}